#include "login_module.h"

#include <boost/asio.hpp>
using namespace boost;
using namespace boost::asio;

#include <common/log/log.h>
#include <common/net/message_parse.h>
#include <common/net/session.h>

#include <protocols/protos/common.pb.h>
using namespace proto::common;
#include <protocols/protos/db.pb.h>
#include <protocols/protos/login.pb.h>
using namespace proto::login;
#include <protocols/protos/tables.pb.h>
using namespace proto::tables;

#include <common/utils/util.h>

#include "base/db_mgr.h"
#include "base/db_server_connection.h"
#include "base/player.h"
#include "base/player_mgr.h"
#include "base/sub_server_mgr.h"

bool LoginModule::doDispatch(const std::shared_ptr<SubServerMgr>& submgr,
                             const std::shared_ptr<Player>& player,
                             const MessageID& msgID,
                             const char* buf,
                             std::size_t bufSize)
{
    switch (msgID.stMsg.msgID)
    {
    case C2S_CHOOSE_PLAYER_REQ:
        return onChoosePlayerReq(submgr, player, msgID, buf, bufSize);

    case C2S_CLIENT_CLOSE_REQ:
        return onClientCloseReq(submgr, player, msgID, buf, bufSize);

    case C2S_TEST_REQ:
        return onTestReq(submgr, player, msgID, buf, bufSize);

    default:
        return false;
    }

    return false;
}

bool LoginModule::onChoosePlayerReq(const std::shared_ptr<SubServerMgr>& submgr,
                                    const std::shared_ptr<Player>& player,
                                    const MessageID& msgID,
                                    const char* buf,
                                    std::size_t bufSize)
{
    ChoosePlayerReq req;
    if (!req.ParseFromArray(buf, bufSize))
    {
        LOG_ERROR("Parse proto data failed.");
        return false;
    }
    LOG_DEBUG("Got login choose req, player_id: " << req.player_id());

    player->onLogin();

    ChoosePlayerRet ret;
    ret.set_err(eFAILED);
    ret.set_err(eSUC);
    player->sendMsg(proto::common::eLogin, proto::login::S2C_CHOOSE_PLAYER_RET, ret);

    return true;
}

bool LoginModule::onClientCloseReq(const std::shared_ptr<SubServerMgr>& submgr,
                                   const std::shared_ptr<Player>& player,
                                   const MessageID& msgID,
                                   const char* buf,
                                   std::size_t bufSize)
{
    player->onLogout();
    return true;
}

bool LoginModule::onTestReq(const std::shared_ptr<SubServerMgr>& submgr,
                            const std::shared_ptr<Player>& player,
                            const MessageID& msgID,
                            const char* buf,
                            std::size_t bufSize)
{
    LOG_DEBUG("got test req.....");

    const auto& otp = player->getProto();
    proto::tables::player tp;
    tp.set_player_id(3);
    tp.set_exp(otp.exp());

    const auto& dbMgr = submgr->getSubMgr<DBMgr>(eDB);
    auto dbConn = dbMgr->getDBConn();
    dbConn.del(player->getID(), &tp);

    return true;
}
